package com.micro.modual.async.completion.realize;

import com.micro.common.MicroConstant;
import com.micro.common.MicroResponseCode;
import com.micro.common.biz.GeneratorCodeUtil;
import com.micro.common.util.SnowFlakeUtil;
import com.micro.core.exception.BizException;
import com.micro.modual.async.completion.enums.CompletionRuleFlag;
import com.micro.modual.async.completion.executor.CompletionRuleExecutor;
import com.micro.modual.entity.UserAccount;
import com.micro.modual.entity.UserNoticeConfig;
import com.micro.modual.entity.UserStatisticsInfo;
import com.micro.modual.mapper.UserAccountMapper;
import com.micro.modual.mapper.UserNoticeConfigMapper;
import com.micro.modual.mapper.UserStatisticsInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;

/**
 * <h2>异步补全用户基础信息</h2>
 * @author LevelCoder
 * @version V1.0.0
 * @email LevelCoder@126.com
 * @date 2020/5/22
 */
@Slf4j
@Component
public class AsyncCompleteUserInformation<T> implements CompletionRuleExecutor<T> {

    @Autowired
    private UserNoticeConfigMapper userNoticeConfigMapper;

    @Autowired
    private UserStatisticsInfoMapper userStatisticsInfoMapper;

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public CompletionRuleFlag ruleConfig() {
        return CompletionRuleFlag.ASYNC_DEFAULT_USER_INFO;
    }

    @Async("getAsyncCompleteUserInformationExecutor")
    @Override
    public void computeRule(T t) {
        log.info("************开始用户信息补全*************");
        String userCode = (String) t;
        //补全用户消息通知默认信息
        UserNoticeConfig userNoticeConfig = splicingNoticeConfig(userCode);
        userNoticeConfigMapper.insertSelective(userNoticeConfig);

        //补全用户统计数据
        UserStatisticsInfo userStatisticsInfo = splicingUserStatisticsInfo(userCode);
        userStatisticsInfoMapper.insertSelective(userStatisticsInfo);

        //补全用户账户 余额账户
        UserAccount userAccountBalance = splicingAccount(userCode, MicroConstant.AccountType.ACCOUNT_BALANCE);
        userAccountMapper.insertSelective(userAccountBalance);
        //补全用户账户 积分账户
        UserAccount userAccountIntegral = splicingAccount(userCode,MicroConstant.AccountType.INTEGRAL_ACCOUNT);
        userAccountMapper.insertSelective(userAccountIntegral);

        //把用户基础信息加入缓存中
        log.info("************结束用户信息补全*************");
    }

    /**
     * <h2>补全账户信息</h2>
     * @param userCode    用户编号
     * @param accountType 账户类别
     * @return
     */
    private UserAccount splicingAccount(String userCode, String accountType) {
        UserAccount userAccount = new UserAccount();
        userAccount.setId(SnowFlakeUtil.getId());
        userAccount.setAccountBalance("0");
        userAccount.setAccountStatus(MicroConstant.StatusEffective.ENABLE);
        userAccount.setFreezeBalance("0");
        userAccount.setUsableBalance("0");
        userAccount.setUserCode(userCode);
        userAccount.setAccountType(accountType);
        userAccount.setCreateTime(new Date());
        userAccount.setAccountNo(findAccountNo(accountType));
        return userAccount;
    }

    /**
     * <h2>根据账户类型获取账户编号</h2>
     * @param accountType
     * @return
     */
    private String findAccountNo(String accountType) {
        String accountNo = null;
        switch (accountType){
            case MicroConstant.AccountType.ACCOUNT_BALANCE:
                accountNo = GeneratorCodeUtil.generatorAccountCode("B");
                break;
            case MicroConstant.AccountType.INTEGRAL_ACCOUNT:
                accountNo = GeneratorCodeUtil.generatorAccountCode("I");
                break;
            default:
                throw new BizException(MicroResponseCode.ACCOUNT_TYPE_ERROR.getResponseCode(),MicroResponseCode.ACCOUNT_TYPE_ERROR.getResponseMessage());
        }
        return accountNo;
    }

    /**
     * <h2>拼接用户统计数据</h2>
     * @param userCode
     * @return
     */
    private UserStatisticsInfo splicingUserStatisticsInfo(String userCode) {
        UserStatisticsInfo userStatisticsInfo = new UserStatisticsInfo();
        userStatisticsInfo.setId(SnowFlakeUtil.getId());
        userStatisticsInfo.setUserCode(userCode);
        userStatisticsInfo.setAssembleOrderCount(0);
        userStatisticsInfo.setCollectProductCount(0);
        userStatisticsInfo.setCommentCount(0);
        userStatisticsInfo.setCouponCount(0);
        userStatisticsInfo.setExchangeOrderCount(0);
        userStatisticsInfo.setCollectProductCount(0);
        userStatisticsInfo.setConsumePrice(new BigDecimal("0"));
        userStatisticsInfo.setLoginCount(0);
        userStatisticsInfo.setTotalOrderCount(0);
        userStatisticsInfo.setSeckillOrderCount(0);
        userStatisticsInfo.setNormalOrderCount(0);
        userStatisticsInfo.setRechargeOrderCount(0);
        userStatisticsInfo.setCreateTime(new Date());
        return userStatisticsInfo;
    }

    /**
     * <h2>拼接用户消息通知状态</h2>
     * @param userCode
     * @return
     */
    private UserNoticeConfig splicingNoticeConfig(String userCode) {
        UserNoticeConfig userNoticeConfig = new UserNoticeConfig();
        userNoticeConfig.setId(SnowFlakeUtil.getId());
        userNoticeConfig.setAccountNoticeStatus(MicroConstant.StatusEffective.ENABLE);
        userNoticeConfig.setServerNoticeStatus(MicroConstant.StatusEffective.ENABLE);
        userNoticeConfig.setOrderNoticeStatus(MicroConstant.StatusEffective.ENABLE);
        userNoticeConfig.setMemberNoticeStatus(MicroConstant.StatusEffective.ENABLE);
        userNoticeConfig.setLogisticsNoiceStatus(MicroConstant.StatusEffective.ENABLE);
        userNoticeConfig.setActivityNoticeStatus(MicroConstant.StatusEffective.ENABLE);
        userNoticeConfig.setUserCode(userCode);
        userNoticeConfig.setCreateTime(new Date());
        return userNoticeConfig;
    }
}
